package edu.umb.cs.antmanager.manager;

import java.awt.*;
import java.awt.event.*;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.HashMap;

import javax.swing.*;

import edu.umb.cs.antmanager.common.ManagerInterface;
import edu.umb.cs.antmanager.common.RMIServerConnector;
import edu.umb.cs.antmanager.domain.MachineType;

public class ManagerControlGUI extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private JList machineList;
	private CloseMe windowCloser;
	private JButton statusButton;
	private JButton shutdownButton;
	private JButton restartButton;
	private JTextArea resultTextArea;
	private ManagerInterface manager;

	public ManagerControlGUI() {
		super();

		setTitle("Ant Manager Contro GUI");
		// program window closing
		windowCloser = new CloseMe();
		this.addWindowListener(windowCloser);

		GridBagLayout gridbag = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		setLayout(gridbag);
		refreshMachineList();
		createButtons();
		resultTextArea = new JTextArea(5, 5);
		resultTextArea.setEditable(false);

		c.fill = GridBagConstraints.BOTH;
		c.weightx = 0.5;
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = GridBagConstraints.REMAINDER;
		add(new JLabel("Machine List"), c);
		c.gridy = 1;
		c.gridwidth = 1;
		c.gridheight = 3;
		add(machineList, c);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.gridheight = 1;
		c.gridx = 2;
		add(statusButton, c);
		c.gridy = 2;
		add(shutdownButton, c);
		c.gridy = 3;
		add(restartButton, c);
		c.gridx = 0;
		c.gridy = 4;
		add(new JLabel("Result"), c);
		c.gridx = 0;
		c.gridy = 6;
		// c.ipady = 80;
		add(resultTextArea, c);

		setSize(400, 250);

		setVisible(true);
	}

	private void createConnection() {
		try {
			manager = RMIServerConnector.createManagerConnector("localhost");
		} catch (MalformedURLException e) {
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (NotBoundException e) {
			e.printStackTrace();
		}
	}

	private void createButtons() {
		ButtonActionListener bl = new ButtonActionListener();
		statusButton = new JButton("Get Status");
		statusButton.setActionCommand("status");
		statusButton.addActionListener(bl);

		shutdownButton = new JButton("Shutdown");
		shutdownButton.setActionCommand("shutdown");
		shutdownButton.addActionListener(bl);

		restartButton = new JButton("Restart");
		restartButton.setActionCommand("restart");
		restartButton.addActionListener(bl);
	}

	private void updateMachineStatus() {
		try {
			HashMap<MachineType, String> mStatus = manager.getMachinesStatus();
			StringBuilder resultBuilder = new StringBuilder();
			Object[] selectedMachines = machineList.getSelectedValues();
			for (Object o : selectedMachines) {
				resultBuilder.append(o.toString() + ":");
				for (MachineType m : mStatus.keySet()) {
					if (m.getName().equals(o.toString())) {
						resultBuilder.append(mStatus.get(m));
						break;
					}
				}
				resultBuilder.append(System.getProperty("line.separator"));
			}
			resultTextArea.setText(resultBuilder.toString());
			resultTextArea.repaint();
			this.repaint();
		} catch (RemoteException e) {
			setResultText("Cannot connect to the manager");
		}
	}

	private void shutdownAgents() {
		try {
			Object[] selectedMachines = machineList.getSelectedValues();
			for (Object o : selectedMachines) {
				manager.shutDownAgent(o.toString());
			}
		} catch (RemoteException e) {
			setResultText("Cannot connect to the manager");
		}
	}

	private void restartAgents() {
		try {
			Object[] selectedMachines = machineList.getSelectedValues();
			for (Object o : selectedMachines) {
				manager.restartAgent(o.toString());
			}
		} catch (RemoteException e) {
			setResultText("Cannot connect to the manager");
		}

	}

	private class ButtonActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			createConnection();
			if (manager == null) {
				setResultText("The Manager is not running");
				return;
			}
			if (e.getActionCommand().equals("status"))
				updateMachineStatus();
			if (e.getActionCommand().equals("shutdown"))
				shutdownAgents();
			if (e.getActionCommand().equals("restart"))
				restartAgents();
		}
	}

	private void refreshMachineList() {
		DefaultListModel listModel = new DefaultListModel();
		for (MachineType m : ResourceManager.getResourceManager().getMachines()) {
			listModel.addElement(m.getName());
		}
		machineList = new JList(listModel);
	}

	private void setResultText(String result) {
		resultTextArea.setText(result);
		resultTextArea.repaint();
	}

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				new ManagerControlGUI();
			}
		});
	}

	private class CloseMe extends WindowAdapter implements ActionListener {
		public void windowClosing(WindowEvent e) {
			this.actionPerformed(null);
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			System.exit(0);
		}
	}
}
